package com.h3c.ptability.aop;

import cn.hutool.core.date.DateUtil;
import cn.hutool.http.Header;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.h3c.ptability.annotation.NeedEosLog;
import com.h3c.ptability.cache.EosTokenCache;
import com.h3c.ptability.cache.UserCache;
import com.h3c.ptability.entity.PtApp;
import com.h3c.ptability.service.IPtAppService;
import com.h3c.ptability.support.eos.EosLog;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.annotation.Order;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

/**
 * @author chenyifan
 * @date 2022/5/7 11:44
 */
@Slf4j
@Aspect
@Component
public class EosLogAspect {

    @Value("${eos.log.url}")
    private String eosLogUrl;

    @Resource
    private IPtAppService ptAppService;


    /**
     * 拦截 @NeedEosLog 注解
     */
    @Pointcut("@annotation(com.h3c.ptability.annotation.NeedEosLog)")
    @Order(8)
    public void authChgPointCut() {
    }


    /**
     * 记录操作日志增强
     */
    @AfterReturning(value = "authChgPointCut()")
    public void operLogAround(JoinPoint jp) {
        log.info("增强中....");
        MethodSignature methodSignature = (MethodSignature) jp.getSignature();
        NeedEosLog needEosLog = methodSignature.getMethod().getAnnotation(NeedEosLog.class);
        String params = JSONUtil.toJsonStr(jp.getArgs()[0]);
        JSONObject parseObj = JSONUtil.parseObj(params);
        HttpServletRequest request = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getRequest();
        String appId = parseObj.getStr("appId");
        PtApp ptApp = ptAppService.getById(appId);
        EosLog eosLog = EosLog.builder()
                .flag(1)
                .level(needEosLog.level())
                .ip(request.getRemoteAddr())
                .requestMethod(request.getMethod())
                .description(needEosLog.value())
                .methodName(methodSignature.getName())
                .userId(UserCache.getLoginUserId())
                .applicationId(ptApp.getAuthCenterId())
                .serviceId(ptApp.getServiceId())
                .operationType(needEosLog.operationType())
                .requestTime(DateUtil.current())
                .requestUrl(request.getRequestURI())
                .parameters(params)
                .build();
        String backStr = HttpRequest.post(eosLogUrl)
                .body(JSONUtil.toJsonStr(eosLog))
                .header(Header.CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE)
                .header(Header.AUTHORIZATION, EosTokenCache.getEosToken()).execute().body();
        log.info("AOP记录授权操作日志返回:{}", backStr);
        JSONObject jsonObject = JSONUtil.parseObj(backStr);
        if(20210 != jsonObject.getInt("code")){
            log.error("AOP记录授权操作日志失败,原因:{}",jsonObject.getStr("message"));
        }
        return;
    }


}
